using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;

public class Sword_Skill_Controller : MonoBehaviour
{
    private Animator anim;
    private Rigidbody2D rb;
    private CircleCollider2D cd;
    private Player player;

    private bool canRotate = true;// 是否扔剑出去的时候跟随重力转动角度
    private bool isReturning;// 剑是否在返回中

    private float freezeTimeDuration;// 攻击到怪物的时候冻结时间
    private float returnSpeed = 12;// 返回的速度


    [Header("刺穿Pierec")]
    private float pierceAmount;// 能刺穿的敌人数量

    [Header("反弹Bounce info")]
    private float bounceSpeed = 20;// 反弹速度
    private bool isBouncing;// 是否反弹
    private int bounceAmount;// 反弹次数
    private List<Transform> enemyTarget;// 反弹敌人列表
    private int targetIndex;// 敌人索引

    [Header("旋转Spin info")]
    private float maxTravelDistance;// 最大距离
    private float spinDuration;// 旋转时间
    private float spinTimer;// 计时器
    private bool spinTimerBool;// 计时器防止重置开关

    private bool wasStopped;// 旋转是否到达最大距离
    private bool isSpinning;// 是否旋转

    private float spinDirection;// 旋转移动距离

    private float hitTimer;// 旋转攻击间隔计时
    private float hitCooldown;// 旋转攻击冷却

    private void Awake()
    {
        anim = GetComponentInChildren<Animator>();
        rb = GetComponent<Rigidbody2D>();
        cd = GetComponent<CircleCollider2D>();
    }

    private void DestroyMe()
    {
        Destroy(gameObject);
    }

    private void Update()
    {
        // 剑飞出去转角
        if (canRotate)// 控制剑的旋转，取消的话剑插在哪里都是横着的
        {
            transform.right = rb.velocity;
        }

        // 剑飞回来
        if (isReturning)
        {
            // 平滑移动剑到角色上
            transform.position = Vector2.MoveTowards(transform.position, player.transform.position, returnSpeed * Time.deltaTime);
            if (Vector2.Distance(transform.position, player.transform.position) < 1)
            {
                player.CatchTheSword();
            }
        }

        // 反弹
        BounceLogic();

        // 旋转
        SpinLogic();
    }

    // 到达最大距离时停止并旋转
    private void StopWhenSpinning()
    {
        if (spinTimerBool) return;
        wasStopped = true;
        rb.constraints = RigidbodyConstraints2D.FreezePosition;
        spinTimer = spinDuration;
        spinTimerBool = true;
    }

    // 剑的旋转
    private void SpinLogic()
    {
        if (isSpinning)
        {
            if (Vector2.Distance(player.transform.position, transform.position) > maxTravelDistance && !wasStopped)
            {
                StopWhenSpinning();
            }
            if (wasStopped)
            {
                transform.position = Vector2.MoveTowards(transform.position, new Vector2(transform.position.x + spinDirection, transform.position.y), 1.5f * Time.deltaTime);

                spinTimer -= Time.deltaTime;

                if (spinTimer < 0)
                {
                    isReturning = true;
                    isSpinning = false;
                }
                hitTimer -= Time.deltaTime;
                if (hitTimer < 0)
                {
                    hitTimer = hitCooldown;// 重置冷却
                    Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 1);// 获取周围的碰撞体
                    foreach (var hit in colliders)
                    {
                        if (hit.GetComponent<Enemy>() != null)// 攻击敌人
                        {
                            SwordSkillDamage(hit.GetComponent<Enemy>());
                        }
                    }
                }
            }
        }
    }

    // 剑的反弹
    private void BounceLogic()
    {
        if (isBouncing && enemyTarget.Count > 0)
        {
            transform.position = Vector2.MoveTowards(transform.position, enemyTarget[targetIndex].position, bounceSpeed * Time.deltaTime);
            if (Vector2.Distance(transform.position, enemyTarget[targetIndex].position) < .1f)
            {
                SwordSkillDamage(enemyTarget[targetIndex].GetComponent<Enemy>());

                targetIndex++;
                bounceAmount--;
                if (bounceAmount <= 0)
                {
                    isBouncing = false;
                    isReturning = true;
                }
                if (targetIndex >= enemyTarget.Count)
                {
                    targetIndex = 0;
                }
            }
        }
    }

    // 设置剑的参数
    public void SetupSword(Vector2 _dir, float _gravityScale, Player _player, float _freezeTimeDuration, float _returnSpeed)
    {
        player = _player;
        freezeTimeDuration = _freezeTimeDuration;
        returnSpeed = _returnSpeed;
        rb.velocity = _dir;
        rb.gravityScale = _gravityScale;
        if (pierceAmount <= 0)
            anim.SetBool("Rotation", true);// 开启旋转动画

        spinDirection = Mathf.Clamp(rb.velocity.x, -1, 1);

        Invoke("DestroyMe", 7);
    }

    #region 
    // 设置投掷为反弹 
    public void SetupBounce(bool _isBouncing, int _bounceAmount, float _bounceSpeed)
    {
        isBouncing = _isBouncing;// 允许反弹
        bounceAmount = _bounceAmount;// 反弹次数
        bounceSpeed = _bounceSpeed;// 反弹速度
        enemyTarget = new List<Transform>();// 初始化列表不然报错
    }

    // 设置投掷为刺穿 
    public void SetupPierce(int _pierceAmount)
    {
        pierceAmount = _pierceAmount;
    }

    // 设置投掷为旋转
    public void SetupSpin(bool _isSpinning, float _maxTravelDistance, float _spinDuration, float _hitCooldown)
    {
        isSpinning = _isSpinning;
        maxTravelDistance = _maxTravelDistance;
        spinDuration = _spinDuration;
        hitCooldown = _hitCooldown;
    }

    #endregion

    // 剑返回到手里
    public void ReturnSword()
    {
        rb.constraints = RigidbodyConstraints2D.FreezeAll;// 没这个有下面那个会先掉到地上
        // rb.isKinematic = false;// 受物理系统影响
        transform.parent = null;// 清除父节点
        isReturning = true;// 返回中
    }

    // 剑插在敌人身上或地上
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (isReturning) return;// 返回中不碰撞

        if (other.GetComponent<Enemy>() != null)
        {
            Enemy enemy = other.GetComponent<Enemy>();
            SwordSkillDamage(enemy);// 伤害

        }

        SetupTargetsForBounce(other);

        StuckInfo(other);// 剑碰撞卡住
    }

    // 对敌人造成伤害并冻结以及脆弱一段时间
    private void SwordSkillDamage(Enemy enemy)
    {
        EnemyStats enemyState = enemy.GetComponent<EnemyStats>();
        player.stats.DoDamage(enemyState);

        if (player.skill.sword.timeStopUnlocked)
            enemy.FreezeTimeFor(freezeTimeDuration);

        if (player.skill.sword.vulnerableUnlocked)
        {
            enemyState.MakeVulnerableFor(freezeTimeDuration);
        }

        ItemData_Equipment equipedAmulet = Inventory.instance.GetEquipment(EquipmentType.Amulet);
        if (equipedAmulet != null)
        {
            equipedAmulet.ExecuteItemEffect(enemy.transform);
        }
    }

    // 反弹获取周围的敌人
    private void SetupTargetsForBounce(Collider2D other)
    {
        if (other.GetComponent<Enemy>() != null)// 剑碰到了怪
        {
            if (isBouncing && enemyTarget.Count <= 0)
            {
                Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 10);// 获取周围的碰撞体
                foreach (var hit in colliders)
                {
                    if (hit.GetComponent<Enemy>() != null)// 使敌人就加入列表
                    {
                        enemyTarget.Add(hit.transform);
                    }
                }
            }
        }
    }

    // 剑碰撞卡住
    private void StuckInfo(Collider2D other)
    {
        if (pierceAmount > 0 && other.GetComponent<Enemy>() != null)// 刺穿
        {
            pierceAmount--;
            return;
        }

        if (isSpinning)//旋转时碰撞会重复重置定时器，给定时器做了个开关
        {
            StopWhenSpinning();
            return;
        }

        canRotate = false;// 旋转关闭
        cd.enabled = false;// 碰撞关闭
        rb.isKinematic = true;// 不受物理系统影响
        rb.constraints = RigidbodyConstraints2D.FreezeAll;// 冻结所有轴
        GetComponentInChildren<ParticleSystem>().Play();// 播放特效

        if (isBouncing && enemyTarget.Count > 0) return;// 反弹过程不关动画
        anim.SetBool("Rotation", false);// 关闭旋转动画
        transform.parent = other.transform;// 改变碰撞到的作为父节点
    }

}
